home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / FIREKIT.ZIP / FLAMES.ASM < prev    next >
Assembly Source File  |  1996-05-27  |  12KB  |  548 lines

  1.     IDEAL
  2.     JUMPS
  3.     P386            ; 386 specific opcodes and shit allowed.
  4.  
  5. ;************************************************************************
  6. ;
  7. ;             FIREKIT v1.0
  8. ;
  9. ;                  by
  10. ;
  11. ;             John W. Ractliff
  12. ;              70253.3237@compuserve.com
  13. ;            jratclif@inlink.com
  14. ;
  15. ;             32bit DOS4GW application.
  16. ;         Will run in Microsoft Windowss 32 bit mode.
  17. ;        Source code in ANSI C and Turbo Assembler
  18. ;
  19. ;
  20. ;The enclosed software was written by John W. Ratcliff on May 27, 1996.
  21. ;As of this date I am releasing this software into the public domain.
  22. ;
  23. ;I am releasing this software into the public domain, hopefully, to make
  24. ;a point.  I would like to demonstrate how to write source code that is
  25. ;useful to other people.  I was looking at some of the various flame
  26. ;algorithms and source code examples and in each case they were such hard
  27. ;coded demos nobody could actually get them integrated into an
  28. ;application.
  29. ;************************************************************************/
  30.  
  31.     MODEL FLAT,C           ;32-bit OS/2 model
  32.  
  33.     public    FlameStart
  34.     public    FlameFrame
  35.     public    FlameCopy
  36.     public    FlameStop
  37.     public    FlameZeroScreen
  38.     public    FlameImage
  39.     public    FlameDAC
  40.     public    FlamePal
  41.     public    FlameCopyTranslate
  42.     public    FlameClosestColor
  43.  
  44. Macro    useall
  45.     uses    ebx,ecx,edx,esi,edi
  46.     endm
  47.  
  48. FWID    equ    320    ; default flame width.
  49.  
  50. Struc    FLAMESPEC
  51.  
  52. width    dd    ?    ; width of flame buffer.
  53. height    dd    ?    ; height of flame buffer.
  54. fsize    dd    ?    ; length, width*height, of flame buffer.
  55. andmask dd    ?    ; fuel dump and mask, controls how many dumps are made.
  56. flame1    dd    ?    ; address of flame buffer #1
  57. flame2    dd    ?    ; address of flame buffer #2
  58. jitter    dd    ?    ; 512 long word jitter table.
  59. seed    dd    ?    ; random number seed.
  60. fheight dd    ?    ; flame consumption value.
  61. fuel    dd    ?    ; size of fuel dumps.
  62. fuelbase dd    ?    ; base fuel fed at bottom.
  63. fire8    dd    ?    ; flag is true if doing 8 pixel average of fire.
  64. ScreenX dd    ?    ; destination screen x copy location.
  65. ScreenY dd    ?    ; destination screen y copy location.
  66. ctrans    db    256 dup(?)    ;the color translation table if used.
  67.  
  68.     Ends
  69.     DATASEG
  70.  
  71. lastwid dd    FWID    ; last width self-modified in the code.
  72.  
  73. label    pal    byte
  74.     rept    8
  75.     db    0,0,0
  76.     endm
  77.  
  78.         i=0
  79.         rept    8
  80.     db    i*2, 0, 0
  81.         i=i+1
  82.         endm
  83.         i=0
  84.         rept    16
  85.         db      16+47*i/16, 0, 0
  86.         i=i+1
  87.         endm
  88.         i=0
  89.         rept    24
  90.         db      63, 21*i/8, 0
  91.         i=i+1
  92.         endm
  93.         i=0
  94.         rept    24
  95.         db      63, 63, 21*i/8
  96.         i=i+1
  97.         endm
  98.  
  99.         db      179*3 dup(63)
  100.  
  101.     CODESEG
  102.  
  103. ;; Init the screen.
  104. Proc    C    FlameStart    near
  105.     useall
  106.  
  107.     mov    eax, 0013h         ; mode 13h
  108.     int    10h        ; turn 320x200 mode on.
  109.  
  110.     mov    edx,3c8h     ; set the color palette.
  111.         xor     al,al
  112.         out     dx,al
  113.         inc     dx
  114.     mov    ecx,256*3
  115.     lea    esi,[pal]
  116.  
  117. @@p1:   mov     al, [esi]
  118.         out     dx, al
  119.     inc    esi
  120.     dec    ecx
  121.         jnz     @@p1
  122.  
  123.     ret
  124.     endp
  125.  
  126. Proc    C    FlameFrame    near
  127.     arg    fl:dword
  128.     local    fuel:dword
  129.     useall
  130.  
  131.     mov    ebx,[fl]
  132.  
  133.     mov    eax,[(FLAMESPEC ebx).width]
  134.     cmp    eax,[lastwid]    ; same as current modification?
  135.     je    @@OK
  136.  
  137. ;; Here we must self-modify all of the instructions which have
  138. ;; hard-coded offsets based on the width of the image being filtered.
  139. ;; There is no way around this self-modified code, period!
  140. ;; The first 8 instructions to modify all have an offset of 3 bytes
  141. ;; While MOD9-MOD12 have an offset of 2 bytes
  142.     mov    edx,eax     ; EDX has -width.
  143.     neg    edx        ;
  144.     mov    [MOD1+3],edx    ; -WIDTH
  145.     mov    [MOD2+3],eax    ; +WIDTH
  146.     inc    eax        ; WIDTH+1
  147.     neg    eax        ; Make it negative
  148.     mov    [MOD3+3],eax    ; -(WIDTH+1)
  149.     neg    eax        ; +(WIDTH+1)
  150.     mov    [MOD4+3],eax
  151.     sub    eax,2        ; now equal width-1
  152.     neg    eax        ; -(width-1)
  153.     mov    [MOD5+3],eax
  154.     neg    eax        ; now + (width-1)
  155.     mov    [MOD6+3],eax    ;
  156.     inc    eax        ; back to positive width.
  157.     mov    [MOD7+3],edx    ; -width
  158.     mov    [MOD8+3],eax    ; +width
  159.     mov    [MOD9+2],edx    ; -width
  160.     mov    [MOD10+2],eax    ; +width
  161.     mov    [MOD11+2],edx    ; -width
  162.     mov    [MOD12+2],eax    ; +width
  163.  
  164. @@OK:
  165.  
  166.     mov    eax,[(FLAMESPEC ebx).fuel]
  167.     mov    [fuel],eax
  168.  
  169.     mov    esi,[(FLAMESPEC ebx).flame1]        ; current source frame.
  170.     mov    edi,[(FLAMESPEC ebx).flame2]        ; current destination frame.
  171.     add    esi,[(FLAMESPEC ebx).width]
  172.     inc    esi        ; width +1
  173.     inc    edi           ; base address of desintation.
  174. ;; ECX = wid*hit-(wid+2)
  175.     mov    ecx,[(FLAMESPEC ebx).fsize]    ; Length of buffer.
  176.     mov    eax,[(FLAMESPEC ebx).width]    ; minus width+2
  177.     shl    eax,1
  178.     add    eax,2
  179.     sub    ecx,eax
  180.  
  181. ;; Each pixel is equal to the mean sum of the one left/right, up and down
  182. ;; on the previous frame.
  183.     mov    edx,[(FLAMESPEC ebx).fheight]    ; height of flame.
  184.     cmp    [(FLAMESPEC ebx).fire8],0    ; doing normal 4 pixel average?
  185.     je    @@l1
  186.  
  187. @@k1:
  188. LABEL    MOD1    DWORD
  189.     movzx    ebx,[byte esi-FWID]     ; get first byte.
  190. LABEL    MOD2    DWORD
  191.     movzx    eax,[byte esi+FWID]     ; get next byte
  192.     add    ebx,eax         ; add into total.
  193.     movzx    eax,[byte esi-1]    ; get next byte.
  194.     add    ebx,eax         ; add into total.
  195.     movzx    eax,[byte esi+1]    ; get fourth byte
  196.     add    ebx,eax         ; have complte summation.
  197. LABEL    MOD3    DWORD
  198.     movzx    eax,[byte esi-(FWID+1)]
  199.     add    ebx,eax
  200. LABEL    MOD4    DWORD
  201.     movzx    eax,[byte esi+(FWID+1)]
  202.     add    ebx,eax
  203. LABEL    MOD5    DWORD
  204.     movzx    eax,[byte esi-(FWID-1)]
  205.     add    ebx,eax
  206. LABEL    MOD6    DWORD
  207.     movzx    eax,[byte esi+(FWID-1)]
  208.     add    eax,ebx
  209.     shr    eax,3
  210.     sub    eax,edx
  211.     jns    @@k2
  212.     xor    eax,eax
  213. @@k2:    mov    [edi],al    ; store result.
  214.     inc    edi
  215.     inc    esi
  216.     dec    ecx
  217.     jnz    @@k1
  218.  
  219.     jmp    @@cont    ; re-enter rest of code.
  220.  
  221. @@l1:
  222. LABEL    MOD7    DWORD
  223.     movzx    ebx,[byte esi-FWID]     ; get first byte.
  224. LABEL    MOD8    DWORD
  225.     movzx    eax,[byte esi+FWID]     ; get next byte
  226.     add    ebx,eax         ; add into total.
  227.     movzx    eax,[byte esi-1]    ; get next byte.
  228.     add    ebx,eax         ; add into total.
  229.     movzx    eax,[byte esi+1]    ; get fourth byte
  230.     add    eax,ebx         ; have complte summation.
  231.     shr    eax,2
  232.     sub    eax,edx
  233.     jns    @@l2
  234.     xor    eax,eax
  235. @@l2:
  236.     mov    [edi],al    ; store result.
  237.     inc    edi
  238.     inc    esi
  239.     dec    ecx
  240.         jnz     @@l1
  241. @@cont:
  242.  
  243. ;; Randomize the bottom 3 scanlines of next frame.
  244.     mov    edx,69069        ; a prime number.
  245.     mov    ebx,[fl]        ; address of flamespec
  246.     mov    edi,[(FLAMESPEC ebx).flame2]            ; destination.
  247.     mov    eax,[(FLAMESPEC ebx).width]
  248.     shl    eax,1
  249.     add    edi,[(FLAMESPEC ebx).fsize]    ; add size of buffer.
  250.     sub    edi,eax     ; less width *2
  251.     mov    ecx,[(FLAMESPEC ebx).width]    ; randomize scanline.
  252.     mov    eax,[(FLAMESPEC ebx).seed]
  253.     mov    ebx,[(FLAMESPEC ebx).fuelbase]
  254.     shl    ebx,8
  255. ;; Adding fuel to the fire.
  256. @@l3:
  257.     imul    eax,edx
  258.     inc    eax        ; Plus 1
  259.     mov    bl,ah
  260.     and    bl,0fh
  261.     add    bl,bh
  262. LABEL    MOD9    DWORD
  263.     mov    [edi-FWID],bl
  264.  
  265.     imul    eax,edx
  266.         inc     eax
  267.     mov    bl,ah
  268.     and    bl,0fh
  269.     add    bl,bh
  270.     mov    [edi],bl
  271.  
  272.     imul    eax,edx
  273.         inc     eax
  274.     mov    bl,ah
  275.     and    bl,0fh
  276.     add    bl,bh
  277.     add    bl,bh
  278. LABEL    MOD10    DWORD
  279.     mov    [edi+FWID],bl
  280.     inc    edi
  281.     dec    ecx
  282.         jnz     @@l3
  283.  
  284. ;; This is a random-jitter function that forces the flames to bubble/roil.
  285. ;; This forces raw fuel into a random number of pixels.
  286.     push    eax    ; preserve current random number.
  287.  
  288.     mov    ebx,[fl]    ; address of flamespec.
  289.     mov    esi,[(FLAMESPEC ebx).flame2]
  290.     add    esi,[(FLAMESPEC ebx).fsize]
  291.     mov    eax,[(FLAMESPEC ebx).width]
  292.     shl    eax,1
  293.     sub    esi,eax     ; bottom scanline-2
  294.     pop    eax
  295.  
  296.     imul    eax,edx
  297.         inc     eax
  298.     mov    cl,al
  299.     and    ecx,[(FLAMESPEC ebx).andmask]    ; and
  300.     jz    @@EMPTY
  301. ; the number of pixel to add fuel to.
  302.     mov    edi,[(FLAMESPEC ebx).jitter]    ; get 512 dword jitter table.
  303.  
  304. ;; EAX/EDX random number.
  305. ;; EBX - scratch.
  306. ;; ECX - Count.
  307. ;; ESI - base for scanline.
  308. ;; EDI - base address of 512 entry jitter table.
  309.  
  310. @@l4:    imul    eax,edx
  311.     inc    eax        ; compute random
  312.     mov    ebx,eax     ; random into EBX
  313.     xchg    bl,bh        ; swap low/high to make it interesting.
  314.     and    ebx,511     ; top 512 entries.
  315.     mov    ebx,[edi+ebx*4] ; pull *valid* offset from jitter table.
  316.     add    ebx,esi     ; plus base.
  317.     push    eax        ; preserve current random number.
  318.  
  319. ;; Fuel Dump
  320.  
  321.     mov    eax,[fuel]
  322. LABEL    MOD11    DWORD
  323.     mov    [ebx-FWID],al    ; dump line above.
  324. LABEL    MOD12    DWORD
  325.     mov    [ebx+FWID],al    ; dump line below.
  326.  
  327.     mov    [ebx-1],al    ; dump left
  328.     mov    [ebx+1],al    ; dump right
  329.     mov    [ebx],al    ; dump current.
  330.  
  331.     pop    eax
  332.  
  333.     dec    ecx
  334.         jnz     @@l4
  335. @@EMPTY:
  336.  
  337.     mov    ebx,[fl]
  338.     mov    [(FLAMESPEC ebx).seed],eax
  339.     mov    eax,[(FLAMESPEC ebx).flame1]
  340.     mov    ecx,[(FLAMESPEC ebx).flame2]
  341.     mov    [(FLAMESPEC ebx).flame1],ecx
  342.     mov    [(FLAMESPEC ebx).flame2],eax
  343.  
  344.     ret
  345.     endp
  346.  
  347. ;; This actually copies the flame to the screen, and then flip/flops the
  348. ;; buffers.
  349. Proc    C    FlameCopy    near
  350.     arg    fl:dword
  351.     useall
  352.  
  353.     mov    ebx,[fl]
  354.     mov    esi,[(FLAMESPEC ebx).flame1]
  355.     lea    edi,[0A0000h]    ; in Watcom DOS4gw, hard coded physical address.
  356.  
  357.     mov    eax,320
  358.     imul    [(FLAMESPEC ebx).ScreenY]
  359.     add    eax,[(FLAMESPEC ebx).ScreenX]
  360.     add    edi,eax     ; dest screen scanline.
  361.  
  362.     mov    ecx,[(FLAMESPEC ebx).width]
  363.     shr    ecx,2        ; /4 movsd
  364.     mov    edx,[(FLAMESPEC ebx).height]
  365.     sub    edx,3
  366. @@GO:
  367.     push    edi
  368.     push    ecx
  369.     rep    movsd
  370.     pop    ecx
  371.     pop    edi
  372.     add    edi,320
  373.     dec    edx
  374.     jnz    @@GO
  375.  
  376.  
  377.     ret
  378.     endp
  379.  
  380.  
  381. Proc    C    FlameStop    near
  382.     useall
  383.  
  384.     mov    eax,03h
  385.     int    10h        ; back to text mode.
  386.  
  387.     ret
  388.     endp
  389.  
  390. Proc    C    FlameZeroScreen near
  391.     useall
  392.  
  393.     mov    edi,0A0000h
  394.     xor    eax,eax
  395.     mov    ecx,64000/4
  396.     rep    stosd
  397.  
  398.     ret
  399.     endp
  400.  
  401. Proc    C    FlameImage    near
  402.     arg    image:dword
  403.     useall
  404.  
  405.     mov    esi,[image]
  406.     mov    edi,0A0000h
  407.     mov    ecx,64000/4
  408.     rep    movsd
  409.  
  410.     ret
  411.     endp
  412.  
  413. Proc    C    FlameDAC    near
  414.     arg    fpal:dword
  415.     useall
  416.  
  417.     mov    edx,3c8h     ; set the color palette.
  418.         xor     al,al
  419.         out     dx,al
  420.         inc     dx
  421.     mov    ecx,256*3
  422.     mov    esi,[fpal]
  423.  
  424. @@p1:   mov     al, [esi]
  425.     shr    al,2        ; into 5 bit format.
  426.     out    dx,al
  427.     inc    esi
  428.     dec    ecx
  429.         jnz     @@p1
  430.  
  431.     ret
  432.     endp
  433.  
  434. Proc    C    FlamePal near
  435.     arg    fpal:dword
  436.     useall
  437.  
  438.     mov    edi,[fpal]
  439.     lea    esi,[pal]
  440.     mov    edx,3c8h     ; set the color palette.
  441.         xor     al,al
  442.         out     dx,al
  443.         inc     dx
  444.     mov    ecx,256*3
  445.  
  446. @@p1:    mov    al,[esi]
  447.     shl    al,2
  448.     mov    [edi],al
  449.     shr    al,2
  450.         out     dx, al
  451.     inc    esi
  452.     inc    edi
  453.     dec    ecx
  454.         jnz     @@p1
  455.  
  456.     ret
  457.     endp
  458.  
  459. ;; This actually copies the flame to the screen, and then flip/flops the
  460. ;; buffers.
  461. Proc    C    FlameCopyTranslate     near
  462.     arg    fl:dword,image:dword
  463.     useall
  464.  
  465.     mov    ebx,[fl]
  466.     mov    esi,[(FLAMESPEC ebx).flame1]
  467.     mov    edi,[image]   ; in Watcom DOS4gw, hard coded physical address.
  468.  
  469.     mov    eax,320
  470.     imul    [(FLAMESPEC ebx).ScreenY]
  471.     add    eax,[(FLAMESPEC ebx).ScreenX]
  472.     add    edi,eax     ; dest screen scanline.
  473.  
  474.     mov    ecx,[(FLAMESPEC ebx).width]
  475.     mov    edx,[(FLAMESPEC ebx).height]
  476.     lea    ebx,[(FLAMESPEC ebx).ctrans]    ; base address of color translate table.
  477.     sub    eax,eax     ; zero out EAX
  478.     sub    edx,3        ; Don't do bottom 3 scanlines.
  479. @@GO:
  480.     push    edi
  481.     push    ecx
  482.  
  483.  
  484. @@MERG: mov    al,[esi]
  485.     inc    esi
  486.     cmp    al,4
  487.     jbe    @@M0
  488.     mov    al,[ebx+eax]    ; color translate flame.
  489.     mov    [edi],al
  490. @@M0:    inc    edi
  491.     dec    ecx
  492.     jnz    @@MERG
  493.  
  494.     pop    ecx
  495.     pop    edi
  496.     add    edi,320
  497.     dec    edx
  498.     jnz    @@GO
  499.  
  500.  
  501.     ret
  502.     endp
  503.  
  504. Macro   Error   COLOR
  505.         LOCAL   @@OK
  506.     xor    eax,eax
  507.     lodsb        ; Get color.
  508.     sub    eax,[COLOR]
  509.     jns    @@OK
  510.     neg    eax
  511. @@OK:    push    ebx         ; Save current error.
  512.     mov    ebx,eax       ; Into BX, difference.
  513.     mul    bl        ; Square it.
  514.     pop    ebx         ; Restore current error.
  515.     add    ebx,eax       ; Add into total error.
  516.     endm
  517.  
  518. Proc    C    FlameClosestColor    near
  519.     ARG    PALETTE:DWORD,R:DWORD,G:DWORD,B:DWORD
  520.     LOCAL    DOMINANT:WORD
  521.     useall
  522.  
  523.     mov    esi,[PALETTE]
  524.     mov    edx,0FFFFFFFFh         ; Minimum error initially found.
  525.     xor    ecx,ecx       ; for all 256 colors.
  526. @@FIND:
  527.     mov    al,[esi]      ; Get red
  528.     mov    ah,[esi+1]    ; Get green.
  529.     mov    bl,[esi+2]    ; Get blue.
  530.     xor    ebx,ebx       ; Total error.
  531.     Error    R
  532.     Error    G
  533.     Error    B
  534.     cmp    ebx,edx       ; Less then previous minimum error?
  535.     jae    @@NOT
  536.     mov    edx,ebx       ; New minimum error.
  537.     mov    edi,ecx       ; Save minimum error loc.
  538. @@NOT:    inc    ecx
  539.     cmp    ecx,256
  540.     jne    @@FIND
  541.  
  542.     mov    eax,edi       ; Closest match.
  543.  
  544.     ret
  545.     endp
  546.  
  547.     END
  548.